/*
 * TODO language 
 * Copyright (c) 2010 TODO Team
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef TODO_COMPILER_H
#define TODO_COMPILER_H
#include <map>
#include "types.h"
#include "location.hh"
#include "opcodes.h"

namespace todo
{
class TodoCompiler {
	todo::TodoScope scope;
	todo_opcode *opcode_ptr;
public:
	const yy::location* location;
	TodoType last_type;	
	bool is_file;
	
	TodoCompiler() { }
	~TodoCompiler() { }
	
	void cast_constant_value(TodoType expected_type, TodoData& value) const;
	void debug(void) const;
	void error(const char*) const;
	void finalize(void) const;
	
	void register_var(TodoType&, TodoData&);
	void register_var(TodoType&, const TodoData&, TodoData&);
	void register_func(TodoType, TodoData&);
	void end_register_func(void);
	void add_func_call_arg(TodoData&);
	TodoData func_call(TodoData&);
	void method_call(TodoData&, TodoData&);
	void add_func_arg(TodoType, TodoData&);
	void multiplication(TodoData&, TodoData&, bool) const;
	void division(TodoData&, TodoData&, bool) const;
	void addition(TodoData&, TodoData&, bool) const;
	void subtraction(TodoData&, TodoData&, bool) const;
	void modulo(TodoData&, TodoData&, bool) const;
	void print(TodoData&, bool newline = false) const;
	void change_var(const TodoData&, const TodoData&) const;
	void register_if(TodoData&, TodoData&);
	void register_elsif(TodoData&, const TodoData&, TodoData&) const;
	void register_else(const TodoData&, TodoData&) const;
	void register_endif(const TodoData&) const;
	void ret(TodoData&) const;
	void ret(void) const;
};
} // todo

#endif // TODO_COMPILER_H
